﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace luceneindex
{
    public class LuceneSearch
    {
        /*
         * TermQuery: 如果你想执行一个这样的查询："在content域中包含'lucene'的document"，那么你可以用TermQuery：
        Term t = new Term("content", "lucene");
        Query query = new TermQuery(t);
         */

        /* BooleanQuery：如果你想这么查询："在content域中包含java或perl的document"，
         那么你可以建立两个TermQuery并把它们用BooleanQuery连接起来： 
        TermQuery termQuery1 = new TermQuery(new Term("content", "java");
        TermQuery termQuery 2 = new TermQuery(new Term("content", "perl");
        BooleanQuery booleanQuery = new BooleanQuery();
        booleanQuery.add(termQuery 1, BooleanClause.Occur.SHOULD);
        booleanQuery.add(termQuery 2, BooleanClause.Occur.SHOULD);
         */

        /*
        WildcardQuery: 如果你想对某单词进行通配符查询，你可以用WildcardQuery,
        通配符包括'?'匹配一个任意字符和'*'匹配零个或多个任意字符，例如你搜索'use*',
        你可能找到'useful'或者'useless'：
        Query query = new WildcardQuery(new Term("content", "use*");
         */ 

        /*
        PhraseQuery: 你可能对中日关系比较感兴趣，想查找'中'和'日'挨得比较近（5个字的距离内）的文章，超过这个距离的不予考虑，你可以：
        PhraseQuery query = new PhraseQuery();
        query.setSlop(5);
        query.add(new Term("content ", "中"));
        query.add(new Term(“content”, "日"));
         */

        /*
        PrefixQuery: 如果你想搜以"中"开头的词语，你可以用PrefixQuery：
        PrefixQuery query = new PrefixQuery(new Term("content ", "中");
         */

        /*
        FuzzyQuery: FuzzyQuery用来搜索相似的term，使用Levenshtein算法。假设你想搜索跟'wuzza'相似的词语，你可以：
        Query query = new FuzzyQuery(new Term("content", "wuzza"); 
        你可能得到'fuzzy'和'wuzzy'。
         */

        /*
        RangeQuery: 另一个常用的Query是RangeQuery，你也许想搜索时间域从20060101到20060130之间的document，你可以用RangeQuery：
        RangeQuery query = new RangeQuery(new Term("time", "20060101"), new Term("time", "20060130"),true);
        最后的true表示用闭合区间。
         */

        /*
        QueryParser
        看了这么多Query，你可能会问："不会让我自己组合各种Query吧，太麻烦了！"当然不会，lucene提供了一种类似于SQL语句的查询语句，
        我们姑且叫它lucene语句，通过它，你可以把各种查询一句话搞定，lucene会自动把它们查分成小块交给相应Query执行。
        下面我们对应每种 Query演示一下：
        TermQuery可以用“field:key”方式，例如“content:lucene”。
        BooleanQuery中‘与’用‘+’，‘或’用‘ ’，例如“content:java contenterl”。
        WildcardQuery仍然用‘?’和‘*’，例如“content:use*”。
        PhraseQuery用‘~’，例如“content:"中日"~5”。
        PrefixQuery用‘*’，例如“中*”。
        FuzzyQuery用‘~’，例如“content: wuzza ~”。
        RangeQuery用‘[]’或‘{}’，前者表示闭区间，后者表示开区间，例如“time:[20060101 TO 20060130]”，注意TO区分大小写。
        你可以任意组合query string，完成复杂操作，例如“标题或正文包括lucene，并且时间在20060101到20060130之间的文章” 
        可以表示为：“+ (title:lucene content:lucene) +time:[20060101 TO 20060130]”。代码如下：

        Directory dir = FSDirectory.getDirectory(PATH, false);
        IndexSearcher is = new IndexSearcher(dir);
        QueryParser parser = new QueryParser("content", new StandardAnalyzer());
        Query query = parser.parse("+(title:lucene content:lucene) +time:[20060101 TO 20060130]";
        Hits hits = is.search(query);
        for (int i = 0; i < hits.length(); i++)
        {
            Document doc = hits.doc(i);
            System.out.println(doc.get("title");
        }
        is.close();
         */

        /*
        Sort
        有时你想要一个排好序的结果集，就像SQL语句的"order by"，lucene能做到：通过Sort。
        Sort sort Sort("time"); //相当于SQL的“order by time”
        Sort sort = new Sort("time", true); // 相当于SQL的"order by time desc"
        下面是一个完整的例子：

        Directory dir = FSDirectory.getDirectory(PATH, false);
        IndexSearcher is = new IndexSearcher(dir);
        QueryParser parser = new QueryParser("content", new StandardAnalyzer());
        Query query = parser.parse("title:lucene content:lucene";
        RangeFilter filter = new RangeFilter("time", "20060101", "20060230", true, true);
        Sort sort = new Sort("time");
        Hits hits = is.search(query, filter, sort);
        for (int i = 0; i < hits.length(); i++)
        {
            Document doc = hits.doc(i);
            System.out.println(doc.get("title");
        }
        is.close();
         */
    }
}
